HAProxy als reverse proxy met multiple subdomains

In 1 van mijn vorige blogs heb ik een Ansible role aangemaakt voor het installeren van een HAProxy. Met HAProxy kun je een systeem bouwen waarin een website of een tcp stream geproxied en/of geloadbalanced kan worden.
Het wordt pas ingewikkeld als je meerdere websites met zowel http als https wil gaan proxien, waarbij er gebruik wordt gemaakt van een wildecard certificaat.
Toch is dat met HAProxy prima te doen. Je kunt er zelfs dan ook een loadbalancer aanhangen. De onderstaande haproxy.cfg laat zien hoe je dat kan doen:

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

    # turn on stats unix socket
#    stats socket /var/lib/haproxy/stats

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000
#---------------------------------------------------------------------
# Enable stats http://192.168.1.1:55555/haproxy?stats
#---------------------------------------------------------------------
listen  stats   192.168.1.1:55555
        mode            http
        log             global

        maxconn 10

        clitimeout      100s
        srvtimeout      100s
        contimeout      100s
        timeout queue   100s

        stats enable
        stats hide-version
        stats refresh 30s
        stats show-node
        stats auth admin:ChangeThisPassword
        stats uri  /haproxy?stats

#--------------------------------------------------------------------
# https frontend
#--------------------------------------------------------------------

frontend https-in
    bind *:443 ssl crt /etc/ssl/fullchain.pem
    acl host_s_server1_local_net hdr(host) -i server1.local.net
    acl host_s_server2_local_net hdr(host) -i server2.local.net
    acl host_s_server3_local_net hdr(host) -i server3.local.net

    use_backend s.server1.local.net if host_s_server1.local.net
    use_backend s.server2.local.net if host_s_server2.local.net
    use_backend s.server3.local.net if host_s_server3.local.net
#-------------------------------------------------------------------- 
# http frontend 
#-------------------------------------------------------------------- 

frontend http-in
    bind *:80
    acl host_server1_local_net hdr(host) -i server1.local.net
    acl host_server2_local_net hdr(host) -i server2.local.net  
    acl host_server3_local_net hdr(host) -i server3.local.net
    
    use_backend server1.local.net if host_server1_local_net
    use_backend server2.local.net if host_server2_local_net
    use_backend server3.local.net if host_server3_local_net
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------


# server1

backend s.server1.local.net
    mode http
    balance	roundrobin
    option 	httpclose
    option 	forwardfor
    server      server1.local.net1 server1.local.net:443 check ssl verify none

backend server1.local.net
    mode http
    balance	roundrobin
    server      server1.local.net1 server1.local.net:80 check

# server2

backend s.server2.local.net
    mode http
    balance roundrobin
    option  httpclose
    option  forwardfor
    server  server2.local.net1 server2.local.net:443 check ssl verify none

backend server2.local.net
    mode    http
    balance roundrobin
    server  server2.local.net1 server2.local.net:80 check

# server3

backend s.server3.local.net
    mode http
    balance roundrobin
    option  httpclose
    option  forwardfor
    server  server3.local.net1 server3.local.net:443 check ssl verify none

backend server3.local.net
    mode    http
    balance roundrobin
    server  server3.local.net1 server3.local.net:80 check

Hierbij zetten we de wildcard in de fullchain.pem file en daar stoppen we dus de fullchain in (key en certificaten). Wel moet je nog een aantal aanpssingen doen. Aangezien we graag statistieken willen hebben gaan we eerst dit onderdeel aanpassen:
Regel 54: Achter listen passen wehet ip adres aan van de haproxy server
Regel 69: We passen de inlognaam en het wachtwoord aan om toegang te krijgen tot de stats

Hierna kun je onder https frontend en http frontend de host namen aanpassen.

acl host_s_server1_local_net hdr(host) -i server1.local.net

Dit betekend dat als server1.local.net in de header als host staat we gebruik gaan maken van de variable host_s_server1_local_net

use_backend s.server1.local.net if host_s_server1.local.net

Dit betekend dat we vanaf de frontend gebruik gaan maken van backend s.server1.local.net, als de variable host_s_server1.local.net gebruikt wordt. Hiermee sturen we dus feitelijk de server van de frontend naar de backend.

# server1

backend s.server1.local.net
    mode http
    balance roundrobin
    option  httpclose
    option  forwardfor
    server      server1.local.net1 server1.local.net:443 check ssl verify none

backend server1.local.net
    mode http
    balance roundrobin
    server      server1.local.net1 server1.local.net:80 check

Dit is het backend gedeelte welke we voor elke host 1 aanmaken. Het eerste gedeelte is de forward via https, het tweede gedeelte via http.
Zoals je kunt zien staat ook de loadbalancer aan (roundrobin). Dit is om in de toekomst ook nog te kunnen load balancen. Dit kunnen we doen door zowel in het http als in het https gedeelte een nieuwe server toe te voegen.
Voor https:

server      server1.local.net2 server1b.local.net:443 check ssl verify none

Voor http:

server      server1.local.net2 server1b.local.net:80 check

Als je alles ingesteld hebt kun je haproxy starten.
Als je bovenstaande config zou gebruiken kun je vervolgens de statistieken vinden op:
http://192.168.1.1:55555/haproxy?stats en daarna inloggen met de gegevens zoals ze in de configfile staan.